﻿
using System;
using System.Linq;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Threading.Tasks;

using Kalman;
using Newtonsoft.Json.Linq;

namespace QuDao
{
    /// <summary>
    /// 数据表sys_menu关联的业务对象，处理该表相关的业务逻辑
    /// </summary>
    public sealed partial class MenuBO : SingletonBase<MenuBO>
    {
        readonly IFreeSql fsql;
        public MenuBO() : base()
        {
            fsql = ServiceLocator.Instance.GetRequiredService<IFreeSql>();
        }

        #region Generate Code

        /// <summary>
        /// 获取导航菜单
        /// </summary>
        /// <param name="id">主键ID的值</param>
        /// <returns></returns>
        public T GetItem<T>(int id)
        {
            var item = fsql.Select<Menu>().Where(a => a.MenuID == id).ToOne<T>();
            return item;
        }

        ///// <summary>
        ///// 获取导航菜单数据列表
        ///// </summary>
        ///// <param name="pageIndex">页索引，从1开始</param>
        ///// <param name="pageSize">每页记录数，默认10</param>
        ///// <returns></returns>
        //public List<T> GetList<T>(int pageIndex = 1, int pageSize = 10)
        //{
        //    var list = fsql.Select<Menu>().Page(pageIndex, pageSize).ToList<T>();
        //    return list;
        //}

        /// <summary>
        /// 获取导航菜单数据列表
        /// </summary>
        /// <returns></returns>
        public List<T> GetList<T>(int[] ids)
        {
            var list = fsql.Select<Menu>()
                .Where(a => ids.Contains(a.MenuID))
                .OrderByDescending(a => a.SortFlag)
                .ToList<T>();
            return list;
        }

        public int SetEnable(int id, bool isEnable)
        {
            return fsql.Update<Menu>(id).Set(a => a.IsEnable, isEnable).ExecuteAffrows();
        }
        /// <summary>
        /// 删除导航菜单数据
        /// </summary>
        /// <returns>返回影响行数</returns>
        public int Delete(int[] ids)
        {
            var hasChild = fsql.Select<Menu>().Any(a => ids.Contains(a.ParentID));
            if (hasChild) throw new AppException("请先删除子菜单");

            return fsql.Delete<Menu>().Where(a => ids.Contains(a.MenuID)).ExecuteAffrows();
        }

        /// <summary>
        /// 删除导航菜单数据
        /// </summary>
        /// <returns>返回影响行数</returns>
        public int Delete(int id)
        {
            var ids = new int[] { id };
            return Delete(ids);
        }

        /// <summary>
        /// 后台查询数据（分页）
        /// </summary>
        /// <param name="req">分页查询请求对象</param>
        public PagingResult<T> Query<T>(PagingRequest req)
        {
            var select = fsql.Select<Menu>();
            foreach (var item in req.FilterItems)
            {
                switch (item.Field)
                {
                    case "MenuID":
                        select.Where(a => a.MenuID == int.Parse(item.Value));
                        break;
                    //case "MenuType":
                    //    select.Where(a => a.MenuType == int.Parse(item.Value));
                    //    break;
                    case "MenuName":
                        select.Where(a => a.MenuName.Contains(item.Value));
                        break;
                    case "ParentID":
                        select.Where(a => a.ParentID == int.Parse(item.Value));
                        break;
                    default:
                        break;
                }
            }

            //if (!string.IsNullOrEmpty(req.SortExp))
            //{
            //    select.OrderBy(req.SortExp);//自定义排序
            //}
            //else
            //{
            //    select.OrderByDescending(a => a.MenuID);//默认排序
            //}
            select.OrderByDescending(a => a.SortFlag);
            select.OrderByDescending(a => a.MenuID);//默认排序

            var sql = select.ToSql();

            var list = select.Count(out var total).Page(req.PageIndex, req.PageSize).ToList<T>();
            return new PagingResult<T>
            {
                PageIndex = req.PageIndex,
                PageSize = req.PageSize,
                Data = list,
                Total = (int)total
            };
        }

        public PagingResult<Menu> Query(PagingRequest req)
        {
            return Query<Menu>(req);
        }
        #endregion

        public Menu GetItem(int id)
        {
            return GetItem<Menu>(id);
        }

        /// <summary>
        /// 获取菜单字典数据
        /// </summary>
        public Dictionary<int, Menu> GetDic(int menuType)
        {
            var dic = fsql.Select<Menu>()
                .Where(a => a.MenuType == menuType)
                .OrderByDescending(a => a.SortFlag)
                .OrderBy(a => a.MenuID)
                .Limit(10000)
                .ToDictionary(a => a.MenuID); //ToDictionary(a => a.Id, a => new { a.Id, a.Title });
            return dic;
        }

        /// <summary>
        /// 获取菜单数据列表
        /// </summary>
        public IEnumerable<T> GetList<T>(int menuType, bool onlyEnable = false)
        {
            var list = fsql.Select<Menu>()
                .Where(a => a.MenuType == menuType && a.IsEnable)
                .WhereIf(onlyEnable, a => a.IsEnable == true)
                .OrderByDescending(a => a.SortFlag)
                .OrderBy(a => a.MenuID)
                .ToList<T>();
            return list;
        }

        /// <summary>
        /// 获取菜单子节点列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="parentID"></param>
        /// <returns></returns>
        public IEnumerable<T> GetChildList<T>(int menuType, int parentID = 0)
        {
            var list = fsql.Select<Menu>()
                .Where(a => a.MenuType == menuType && a.ParentID == parentID)
                .OrderByDescending(a => a.SortFlag)
                .OrderBy(a => a.MenuID)
                .ToList<T>();
            return list;
        }

        /// <summary>
        /// 新增导航菜单
        /// </summary>
        public int Add(MenuDto dto)
        {
            var entity = new Menu
            {
                MenuName = dto.MenuName,
                Icon = dto.Icon,
                IsEnable = dto.IsEnable,
                Memo = dto.Memo,
                MenuType = dto.MenuType,
                ParentID = dto.ParentID,
                SortFlag = dto.SortFlag,
                Url = dto.Url,
                CreateTime = DateTime.Now,
                ModifyTime = DateTime.Now,
                MenuLevel = 1
            };
            if (dto.ParentID > 0)
            {
                var parent = GetItem(dto.ParentID);
                if (parent != null)
                {
                    entity.MenuLevel = parent.MenuLevel + 1;
                }
            }

            entity.MenuID = (int)fsql.Insert(entity).ExecuteIdentity();
            return entity.MenuID;
        }

        /// <summary>
        /// 修改导航菜单
        /// </summary>
        public int Modify(MenuDto dto)
        {
            var item = GetItem(dto.MenuID) ?? throw new AppException($"导航菜单不存在：{dto.MenuID}");
            var update = fsql.Update<Menu>(dto.MenuID).Set(a => a.ModifyTime, DateTime.Now);

            if (dto.MenuName != item.MenuName) update.Set(a => a.MenuName, dto.MenuName);
            if (dto.ParentID != item.ParentID) update.Set(a => a.ParentID, dto.ParentID);
            //if (dto.MenuLevel != item.MenuLevel) update.Set(a => a.MenuLevel, dto.MenuLevel);
            if (dto.Url != item.Url) update.Set(a => a.Url, dto.Url);
            if (dto.Icon != item.Icon) update.Set(a => a.Icon, dto.Icon);
            if (dto.SortFlag != item.SortFlag) update.Set(a => a.SortFlag, dto.SortFlag);
            if (dto.IsEnable != item.IsEnable) update.Set(a => a.IsEnable, dto.IsEnable);
            if (dto.Memo != item.Memo) update.Set(a => a.Memo, dto.Memo);

            return update.ExecuteAffrows();
        }

    }
}
